package com.links.sbademo;


import java.util.UUID;

import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import de.codecentric.boot.admin.server.config.AdminServerProperties;
import jakarta.servlet.DispatcherType;

/** 
* @author : lichun
* @date ：02-二月-24 下午 02:28 
* 
*/
@Configuration(proxyBeanMethods = false)
public class SecurityConfig {

        private final AdminServerProperties adminServer;

        private final SecurityProperties security;

        public SecurityConfig(AdminServerProperties adminServer, SecurityProperties security) {
                this.adminServer = adminServer;
                this.security = security;
        }

        @Bean
        protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
                successHandler.setTargetUrlParameter("redirectTo");
                successHandler.setDefaultTargetUrl(this.adminServer.path("/"));

                http.authorizeHttpRequests((authorizeRequests) -> authorizeRequests //
                        .requestMatchers(new AntPathRequestMatcher(this.adminServer.path("/assets/**")))
                        .permitAll() 
                        .requestMatchers(new AntPathRequestMatcher(this.adminServer.path("/actuator/info")))
                        .permitAll()
                        .requestMatchers(new AntPathRequestMatcher(adminServer.path("/actuator/health")))
                        .permitAll()
                        .requestMatchers(new AntPathRequestMatcher(this.adminServer.path("/login")))
                        .permitAll()
                        .dispatcherTypeMatchers(DispatcherType.ASYNC)
                        .permitAll() // https://github.com/spring-projects/spring-security/issues/11027
                        .anyRequest()
                        .authenticated()) 
                        .formLogin(
                                        (formLogin) -> formLogin.loginPage(this.adminServer.path("/login")).successHandler(successHandler)) 
                        .logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout")))
                        .httpBasic(Customizer.withDefaults()); 

                
//                http.addFilterAfter(new CsrfFilter(CookieCsrfTokenRepository.withHttpOnlyFalse()), BasicAuthenticationFilter.class) 
//                        .csrf((csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
//                                .csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler())
//                                .ignoringRequestMatchers(
//                                                new AntPathRequestMatcher(this.adminServer.path("/instances"), "POST"), 
//                                                new AntPathRequestMatcher(this.adminServer.path("/instances/*"), "DELETE"), 
//                                                new AntPathRequestMatcher(this.adminServer.path("/actuator/**")) 
//                                ));

                http.rememberMe((rememberMe) -> rememberMe.key(UUID.randomUUID().toString()).tokenValiditySeconds(1209600));

                return http.build();

        }

  

  
      

        // Required to provide UserDetailsService for "remember functionality"
        @Bean
        public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {
                UserDetails user = User.withUsername("admin").password(passwordEncoder.encode("Links@2023")).roles("USER").build();
                return new InMemoryUserDetailsManager(user);
        }

        @Bean
        public PasswordEncoder passwordEncoder() {
                return new BCryptPasswordEncoder();
        }

}
